出处:掘金
原作者:金泽宸
instanceof 吗?面试官为什么问这个问题:
a instanceof B 本质判断的是:B.prototype 是否在 a.__proto__ 的原型链上。即:
a.__proto__ === B.prototype
a.__proto__.__proto__ === B.prototype
a.__proto__.__proto__.__proto__ === B.prototype
// ...
// 直到 __proto__ === null 为止
instanceof 仅适用于对象,原始类型(如 number、string)会返回 falseconsole.log('str' instanceof String); // false,需用 new String() 创建对象
({}) instanceof null; // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
prototype 属性,可能导致 instanceof 结果异常instanceoffunction myInstanceof(obj, constructor) {
if (typeof obj !== 'object' || obj === null) return false;
if (typeof constructor !== 'object' || constructor === null) {
throw new TypeError(`Right-hand side of 'instanceof' is not an object`);
}
let proto = Object.getPrototypeOf(obj); // 相当于 obj.__proto__
const prototype = constructor.prototype;
while (proto) { // 当proto == null 时,说明已经找到了 Object 的基类 null,退出循环
if (proto === prototype) return true;
proto = Object.getPrototypeOf(proto); // 向上查找
}
return false;
}
| 易错点 | 正解 |
|---|---|
忘了处理 null |
typeof obj !== 'object' || obj === null |
直接 __proto__ |
推荐用 Object.getPrototypeOf() 更规范 |
| 判断条件错误 | proto === constructor.prototype,不要搞混 |
实际上 a instanceof B 会调用:
B[Symbol.hasInstance](a)
你甚至可以这样 hack:
class A {
static [Symbol.hasInstance](obj) {
return false;
}
}
console.log(new A() instanceof A); // false !!!
这是 instanceof 可被重写的入口,了解这个能在面试中加分